#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

// #define N 10

template<class T, size_t N = 10>
class Array
{
    T _a[N];
};

template<bool N>
void func()
{
    cout << N << endl;
}

// template<double N>
// void func()
// {
//
// }


class date
{
    friend ostream& operator<<(ostream& _cout, const date& d);

public:
    date(int year = 1900, int month = 1, int day = 1)
        : _year(year)
        , _month(month)
        , _day(day)
    {}

    bool operator<(const date& d) const
    {
        return (_year < d._year)
               || (_year == d._year && _month < d._month)
               || (_year == d._year && _month == d._month && _day < d._day);
    }

    bool operator>(const date& d) const
    {
        return (_year > d._year)
               || (_year == d._year && _month > d._month)
               || (_year == d._year && _month == d._month && _day > d._day);
    }

private:
    int _year;
    int _month;
    int _day;
};

ostream& operator<<(ostream& _cout, const date& d)
{
    return cout << d._year << "-" << d._month << "-" << d._day;
}

// template<class T>
// bool less(T l, T r)
// {
//     return l < r;
// }

// template<>
// bool less<date*>(date* d1, date* d2)
// {
//     return *d1 < *d2;
// }

// bool less(date* d1, date* d2)
// {
//     return *d1 < *d2;
// }

template<class T>
struct less
{
    bool operator()(const T l, const T r)
    {
        return l < r;
    }
};

template<class T>
struct less<T*>
{
    bool operator()(const T* l, const T* r)
    {
        return l < r;
    }

};

template<>
struct less<date*>
{
    bool operator()(const date* l, const date* r)
    {
        return l < r;
    }
};

int main()
{
    Array<int, 10> a1;
    Array<double, 20> a2;

    func<true>();
    func<false>();

    // cout << less(1, 2) << endl;
    // cout << less(date(2020, 1, 2), date(2020, 3, 3)) << endl;
    // cout << less(new date(2020, 1, 2), new date(2020, 3, 3)) << endl;

    cout << less<int*>()(new int(1), new int(2)) << endl;
    cout << less<date>()(date(2020, 1, 2), date(2020, 3, 3)) << endl;
    cout << less<date*>()(new date(2020, 1, 2), new date(2020, 3, 3)) << endl;

    return 0;
}